package ssau.knyazev.core;

public class ComplexMath {

	public static Complex sin(Complex x){
		Complex z1 = Complex.exp(x.getReal());
		double z11 = Math.exp(-x.getImg());
		z1 = z1.multyBy(z11);
		
		Complex z2 = Complex.exp(-x.getReal());
		double z22 = Math.exp(x.getImg());
		z2 = z2.multyBy(z22);
		
		z1 = z1.sub(z2);
		z1 = z1.devide(new Complex(0, 2));

		return z1;
	}
	
	public static Complex cos(Complex x){
		Complex z1 = Complex.exp(x.getReal());
		double z11 = Math.exp(-x.getImg());
		z1 = z1.multyBy(z11);
		
		Complex z2 = Complex.exp(-x.getReal());
		double z22 = Math.exp(x.getImg());
		z2 = z2.multyBy(z22);
		
		z1 = z1.add(z2);
		z1 = z1.devideBy(2);

		return z1;
	}
	
	public static Complex acos(Complex x){
		org.apache.commons.math.complex.Complex t = new org.apache.commons.math.complex.Complex(x.getReal(), x.getImg());
		t = t.acos();
		return new Complex((float)t.getReal(), (float)t.getImaginary());
	}
	
	public static Complex sqrt(Complex x){
		org.apache.commons.math.complex.Complex t = new org.apache.commons.math.complex.Complex(x.getReal(), x.getImg());
		t = t.sqrt();
		return new Complex((float)t.getReal(), (float)t.getImaginary());
	}
	
	public static Complex[][] matrixMultiplication(Complex[][] a, Complex[][] b){
		Complex[][] res = new Complex[a.length][b[0].length];
		for (int i = 0; i < res.length; i++){
			for (int j = 0; j < res[0].length; j++){
				res[i][j] = new Complex();
				for (int k = 0; k < a[0].length; k++){
					res[i][j] = res[i][j].add(a[i][k].multy(b[k][j]));
				}
			}
		}
		return res;
	}
	
	public static Complex[][] elementMatrixMultiplication(Complex[][] a, Complex[][] b) throws Exception{
		if (a.length != b.length || a[0].length != b[0].length){
			throw new Exception("Different matrix sizes");
		}
		Complex[][] res = new Complex[a.length][a[0].length];
		for (int i = 0; i < res.length; i++){
			for (int j = 0; j < res[0].length; j++){
				res[i][j] = a[i][j].multy(b[i][j]);
			}
		}
		return res;
	}
	
	public static Complex[][] elementMatrixDevision(Complex[][] a, Complex[][] b) throws Exception{
		if (a.length != b.length || a[0].length != b[0].length){
			throw new Exception("Different matrix sizes");
		}
		Complex[][] res = new Complex[a.length][a[0].length];
		for (int i = 0; i < res.length; i++){
			for (int j = 0; j < res[0].length; j++){
				res[i][j] = a[i][j].devide(b[i][j]);
			}
		}
		return res;
	}
	
	public static Complex[][] matrixAddition(Complex[][] a, Complex[][] b){
		Complex[][] res = new Complex[a.length][a[0].length];
		for (int i = 0; i < res.length; i++){
			for (int j = 0; j < res[0].length; j++){
				res[i][j] = a[i][j].add(b[i][j]);
			}
		}
		return res;
	}
	
	public static Complex[][] elementLinkedMultiplication(Complex[][] a, Complex[][] b){
		Complex[][] res = new Complex[a.length][a[0].length];
		for (int i = 0; i < res.length; i++){
			for (int j = 0; j < res[0].length; j++){
				res[i][j] = a[i][j].multy(b[i][j]);
				res[i][j] = ComplexMath.sqrt(res[i][j]);
			}
		}
		return res;
	}
	
}
